/*
 * Adara WebCam TimeLapse capture software.
 * Copyright (C) 2012 AdaraProjectTeam
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package adara.cli;

import java.io.File;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;

/**
 * The class which read and parse the arguments provided.
 * @author Andrei Ermicioi (aka erani) <andrei.ermicioi@gmail.com>
 *
 */
public class CLICommand {
	
	private CommandLine cmd;
	private Options options;
	
	private CLICommand(CommandLine cmd, Options options) {
		this.cmd = cmd;
		this.options = options;
	}
	
	public CommandType getCommand() {
		if (cmd.hasOption("capture")) {
			return CommandType.CAPTURE;
		}
		
		if (cmd.hasOption("list")) {
			return CommandType.LIST;
		}
		
		if (cmd.hasOption("info")) {
			return CommandType.INFO;
		}
		
		return CommandType.HELP;
	}
	
	public int getDevice() {
		return Integer.valueOf(cmd.getOptionValue("device"));
	}
	
	public File getStorage() {
		return new File(cmd.getOptionValue("storage"));
	}
	
	public int getGap() {
		return Integer.valueOf(cmd.getOptionValue("gap"));
	}
	
	public int getTime() {
		return Integer.valueOf(cmd.getOptionValue("time"));
	}
	
	public Options getOptions() {
		return options;
	}
	
	public static CLICommand factory(String argc[]) throws CLIException {
		Options options = factoryOptions();
		CommandLine cmd = null;
		
		try {
			cmd = new GnuParser().parse(options, argc);
		} catch (ParseException e) {
			throw new CLIException("Could not obtain command line", e);
		}
		
		CLICommandValidator.validate(cmd);
		
		return new CLICommand(cmd, options);
	}
	
	private static Options factoryOptions() {
		Option helpOption = new Option("h", "help", false, "Print the list of options");
		Option listOption = new Option("l", "list", false, "List available devices");
		Option infoOption = new Option("i", "info", false, "Show the information about device");
		Option captureOption = new Option("c", "capture", false, "Starts the capturing process");

		OptionBuilder.withArgName("directory");
		OptionBuilder.hasArg();
		OptionBuilder
				.withDescription("The directory where images will be stored");
		Option storageOption = OptionBuilder.create("s");
		storageOption.setLongOpt("storage");

		OptionBuilder.withArgName("device sequence");
		OptionBuilder.hasArg();
		OptionBuilder.withDescription("The device on which to capture");
		Option deviceOption = OptionBuilder.create("d");
		deviceOption.setLongOpt("device");

		OptionBuilder.withArgName("seconds");
		OptionBuilder.hasArg();
		OptionBuilder.withDescription("The amount of seconds between capture");
		Option gapOption = OptionBuilder.create("g");
		gapOption.setLongOpt("gap");

		OptionBuilder.withArgName("seconds");
		OptionBuilder.hasArg();
		OptionBuilder
				.withDescription("The time in second for how long to capture images");
		Option durationOption = OptionBuilder.create("t");
		durationOption.setLongOpt("time");

		Options options = new Options();
		options.addOption(helpOption);
		options.addOption(listOption);
		options.addOption(gapOption);
		options.addOption(infoOption);
		options.addOption(captureOption);
		options.addOption(storageOption);
		options.addOption(deviceOption);
		options.addOption(durationOption);

		return options;
	}

	public enum CommandType {
		CAPTURE,
		LIST,
		INFO,
		HELP;
	}
}
